package cn.qlin.mvc.orm.util;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import cn.qlin.mvc.orm.annotation.Id;
import cn.qlin.mvc.orm.annotation.OneTOMany;
import cn.qlin.mvc.orm.annotation.TableCol;
import cn.qlin.mvc.orm.bean.UpdateTable;
import cn.qlin.mvc.orm.db.KeyTactics;
import cn.qlin.util.Reflect;

/**
 * @author 吴延麟
 * 描述：该类主要用来操作bean
 * */
public class BeanOperate {
	/**
	 * 描述：通过字段名获取对应获取属性方法名
	 * */
	public static String getGetMethodName(String fildeName) throws Exception{  
        byte[] items = fildeName.getBytes();  
        items[0] = (byte) ((char) items[0] - 'a' + 'A');  
        return "get"+new String(items);
    }
	/**
	 * 描述：通过字段名获取对应设置属性方法名
	 * */
	public static String getSetMethodName(String fildeName) throws Exception{  
        byte[] items = fildeName.getBytes();  
        items[0] = (byte) ((char) items[0] - 'a' + 'A');  
        return "set"+new String(items); 
    } 
	/**
	 * 描述：通过实例获取属性非id的键值对
	 * */
	public static Map<String, String> getNonIdKaV(Object obj){
		Map<String, String> maps = new HashMap<String, String>();
		Reflect reflect = new Reflect(obj.getClass());
		Field[] fields = reflect.getMethodNames();
		for(int i=0;i<fields.length;i++){
			String key = ORMAnnotationOpen.getIdtoKey(fields[i]);
			Object robj =  ORMAnnotationOpen.getFiledToValue(obj, fields[i]);
			if(("".equals(key))){
				OneTOMany onetomany = fields[i].getAnnotation(OneTOMany.class);
				if(onetomany==null){
					key = ORMAnnotationOpen.getFiledNameToKey(fields[i]);
					if(robj == null){
						maps.put(key,null);
					}else{
						maps.put(key, "'"+robj.toString()+"'");
					}
				}else{
					System.out.println(Reflect.getFieldValue(obj, fields[i]));
				}
			}
		}
		return maps;
    } 
	/**
	 * 描述：获取id的映射名字
	 * */
	public static String getIdToName(Class<?> clz){
		Reflect reflect = new Reflect(clz);
		Field[] fields = reflect.getMethodNames();
		for(int i=0;i<fields.length;i++){
			String key = ORMAnnotationOpen.getIdtoKey(fields[i]);
			if(!(("".equals(key)))){
				return key;
			}
		}
		return "";
    } 
	/**
	 * 描述：通过实例获取属性所有的键值对
	 * */
	public static Map<String, String> getKaV(Object obj){
		Map<String, String> maps = new HashMap<String, String>();
		Reflect reflect = new Reflect(obj.getClass());
		Field[] fields = reflect.getMethodNames();
		for(int i=0;i<fields.length;i++){
			String key = ORMAnnotationOpen.getFiledNameToKey(fields[i]);
			Object robj =  ORMAnnotationOpen.getFiledToValue(obj, fields[i]);
			if(!("".equals(key))){
				key = ORMAnnotationOpen.getFiledNameToKey(fields[i]);
				if(robj == null){
					maps.put(key,"''");
				}else{
					maps.put(key, robj.toString());
				}
			}
		}
		return maps;
    } 
	/**
	 * 描述：通过实例获取属性id的键值对
	 * */
	public static String[] getIdKaV(Object obj){
		String[] str = new String[2];
		Reflect reflect = new Reflect(obj.getClass());
		Field[] fields = reflect.getMethodNames();
		for(int i=0;i<fields.length;i++){
			String key = ORMAnnotationOpen.getIdtoKey(fields[i]);
			Object robj =  ORMAnnotationOpen.getFiledToValue(obj, fields[i]);
			if(!("".equals(key))){
				if(robj == null){
					str[0] = key;
					str[1] = "''";
				}else{
					str[0] = key;
					str[1] = robj.toString();
				}
			}
		}
		return str;
    } 
	/**
	 * 描述：通过实例获取属性id的键值对
	 * */
	public static String[] getIdTactics(Object obj){
		String[] str = new String[2];
		Reflect reflect = new Reflect(obj.getClass());
		Field[] fields = reflect.getMethodNames();
		for(int i=0;i<fields.length;i++){
			String key = ORMAnnotationOpen.getIdtoKey(fields[i]);
			String value = ORMAnnotationOpen.getIdTactics(fields[i]);
			if(!("".equals(key))){
				str[0] = key;
				str[1] = KeyTactics.getInsert(value);
			}else{
				new Exception("没有定义主键");
			}
		}
		if("".equals(str[0])){
			new Exception("没有定义主键").printStackTrace();
		}
		return str;
    } 
	/**
	 * 描述：获取更新的对象
	 * */
	public static UpdateTable getupdate(Object obj) {
		UpdateTable ut = new UpdateTable();
		Map<String,String> nonids = BeanOperate.getNonIdKaV(obj);
		Set<String> nonid = nonids.keySet();
		for(String key:nonid){
			ut.setCols(key, nonids.get(key));
		}
		String[] str = BeanOperate.getIdKaV(obj);
		Map<String,String> ids = new HashMap<String, String>();
		ids.put(str[0], str[1]);
		Set<String> id = ids.keySet();
		for(String key:id){
			ut.setWhere(key, ids.get(key));
		}
		
		return ut;
	}
	/**
	 * 描述：根据传入属性获取其数据库字段映射
	 * */
	public static String getFieldName(Field field) {
		TableCol col = field.getAnnotation(TableCol.class);
		if(col==null){
			Id id = field.getAnnotation(Id.class);
			if(id == null){
				return "";
			}else if("".equals(id.name())){
				return field.getName();
			}else{
				return id.name();
			}
		}else if("".equals(col.value())){
			return field.getName();
		}else{
			return col.value();
		}
		
	}
	/**
	 * 描述：获取插入键值对
	 * */
	public static Map<String, String> getInsert(Object obj) {
		Map<String, String> map = new HashMap<String, String>();
		Map<String,String> nonids = BeanOperate.getNonIdKaV(obj);
		Set<String> nonid = nonids.keySet();
		for(String key:nonid){
			map.put(key, nonids.get(key));
		}
		String[] str = BeanOperate.getIdTactics(obj);
		map.put(str[0], str[1]);
		return map;
	}
	/**
	 * 描述：获取删除主键
	 * */
	public static String[] getdelete(Object obj) {
		return  BeanOperate.getIdKaV(obj);
	}
	/**
	 * 描述： 获取所有属性的字段名的sql映射
	* */
	public static Map<String,Field> getALLColsName(Class<?> clz){
		Map<String,Field> colsname = new HashMap<String,Field>();
		Field[] fields = clz.getDeclaredFields();
		
		for(int i=0;i<fields.length;i++){
			try {
				TableCol hqls = fields[i].getAnnotation(TableCol.class);
				if(hqls==null){
					Id id = fields[i].getAnnotation(Id.class);
					if(id==null){
						colsname.put(fields[i].getName(),fields[i]);
					}else{
						colsname.put(id.name(),fields[i]);
					}
				}else{
					colsname.put(hqls.value(),fields[i]);
				}
			} catch (Exception e) {
				System.out.println("设置值异常可能不是标准bean");
				e.printStackTrace();
			}
		}
		return colsname;
	}

	
}
